<template>
    <div class="playground" :class="{ 'is-fullscreen': isFullscreen }">
        <!-- 工具栏，仅非全屏时显示 -->
        <div v-if="!isFullscreen" class="toolbar">
            <button class="btn btn-icon" @click="$router.push('/')">
                <i class="icon-back"></i>
                <span>返回</span>
            </button>
            <div class="tabs">
                <button v-for="tab in ['html', 'css', 'javascript']" :key="tab" class="tab"
                    :class="{ active: currentTab === tab }" @click="currentTab = tab">
                    {{ tab === 'javascript' ? 'JavaScript' : tab.toUpperCase() }}
                </button>
            </div>
            <div class="toolbar-actions">
                <button class="btn btn-toggle" :class="{ active: autoRun }" @click="autoRun = !autoRun">
                    <i class="icon-auto-run"></i>
                    <span>实时运行</span>
                    <span v-if="autoRun" class="on">开</span>
                    <span v-else class="off">关</span>
                </button>
                <button class="btn btn-primary" @click="runCode" :class="{ 'is-loading': isRunning }">
                    <i class="icon-run"></i>
                    <span>{{ isRunning ? '运行中...' : '运行' }}</span>
                </button>
                <button class="btn btn-icon" @click="toggleFullscreen">
                    <i :class="isFullscreen ? 'icon-exit-fullscreen' : 'icon-fullscreen'"></i>
                    <span>{{ isFullscreen ? '退出全屏' : '全屏' }}</span>
                </button>
            </div>
        </div>

        <!-- 主容器 -->
        <div class="main-content" :class="{ 'is-fullscreen': isFullscreen }">
            <!-- 编辑器区域，非全屏时显示 -->
            <Transition name="slide-fade">
                <div v-if="!isFullscreen" class="editor-container">
                    <template v-if="!isLoading">
                        <Transition name="fade" mode="out-in">
                            <div class="editor-wrapper" :key="currentTab">
                                <MonacoEditor v-model="codeState[currentTab]" :language="currentTab"
                                    :options="editorOptions" @change="handleCodeChange" />
                                <div class="editor-status-bar">
                                    <span class="status-item">
                                        <i class="status-icon" :class="currentTab"></i>
                                        {{ currentTab.toUpperCase() }}
                                    </span>
                                    <span class="status-item">
                                        <i class="status-icon icon-info"></i>
                                        实时预览已{{ autoRun ? '开启' : '关闭' }}
                                    </span>
                                </div>
                            </div>
                        </Transition>
                    </template>
                    <div v-else class="editor-loading">
                        <div class="loading-spinner"></div>
                        <span>加载中...</span>
                    </div>
                </div>
            </Transition>

            <!-- 预览区域 -->
            <div class="preview-container" :class="{ 'is-fullscreen': isFullscreen }">
                <div class="preview-header">
                    <span class="preview-title">预览</span>
                    <div class="preview-controls">
                        <button v-if="!isFullscreen" class="btn-icon-small" @click="refreshPreview"
                            :disabled="isRunning">
                            <i class="icon-refresh"></i>
                        </button>
                        <!-- 全屏时显示退出全屏按钮 -->
                        <button v-if="isFullscreen" class="btn btn-icon btn-exit-fullscreen" @click="toggleFullscreen">
                            <span>退出全屏</span>
                        </button>
                    </div>
                </div>
                <Transition name="fade">
                    <div v-if="isRunning" class="preview-loading">
                        <div class="loading-spinner"></div>
                        <span>代码运行中...</span>
                    </div>
                </Transition>
                <iframe ref="previewFrame" class="preview-frame" sandbox="allow-scripts allow-same-origin allow-modals"
                    :key="previewKey"></iframe>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import { storeToRefs } from 'pinia'
import { useRoute, useRouter } from 'vue-router'
import { usePlaygroundStore } from '../stores/playground'
import { useExamplesStore } from '../stores/examples'
import MonacoEditor from '../components/MonacoEditor.vue'

const route = useRoute()
const router = useRouter()
const playgroundStore = usePlaygroundStore()
const examplesStore = useExamplesStore()

const previewFrame = ref(null)
const previewKey = ref(0)
const { code: codeState, currentTab, isFullscreen, isLoading } = storeToRefs(playgroundStore)
const isRunning = ref(false)
const autoRun = ref(false)
const isEditorFocused = ref(false)
const showPreview = ref(true)

// 编辑器配置
const editorOptions = {
    theme: 'vs-dark',
    fontSize: 14,
    minimap: { enabled: false },
    scrollBeyondLastLine: false,
    automaticLayout: true,
    lineNumbers: 'on',
    roundedSelection: false,
    cursorStyle: 'line'
}

// 生成预览HTML
const generatePreviewHtml = () => {
    return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    /* 重置样式 */
    body { margin: 0; padding: 0; }
    /* 用户样式 */
    ${codeState.value.css}
  <\/style>
</head>
<body>
  ${codeState.value.html}
  <script>
    window.onerror = function(msg, url, line, col, error) {
      console.error('Error:', msg, 'Line:', line);
      return false;
    };
    try {
      ${codeState.value.javascript}
    } catch (error) {
      console.error('代码执行错误:', error);
    }
  <\/script>
<\/body>

<\/html>`
}

// 更新预览
const updatePreview = () => {
    if (!previewFrame.value) return

    const content = generatePreviewHtml()
    const blob = new Blob([content], { type: 'text/html' })
    const url = URL.createObjectURL(blob)

    previewFrame.value.src = url

    // 清理URL对象
    setTimeout(() => URL.revokeObjectURL(url), 100)
}

// 处理代码变化
const handleCodeChange = () => {
    if (autoRun.value) {
        debouncedRunCode()
    }
}

// 运行代码
const runCode = async () => {
    isRunning.value = true
    try {
        previewKey.value++
        await nextTick()
        updatePreview()
        // 模拟运行延迟
        await new Promise(resolve => setTimeout(resolve, 500))
    } finally {
        isRunning.value = false
    }
}

// 刷新预览
const refreshPreview = () => {
    runCode()
}

// 切换全屏
const toggleFullscreen = () => {
    isFullscreen.value = !isFullscreen.value
    nextTick(() => {
        updatePreview()
    })
}

// 初始化
onMounted(async () => {
    try {
        const example = examplesStore.getExampleById(route.params.id)
        if (!example) {
            router.push('/')
            return
        }

        // 加载示例代码
        playgroundStore.loadExample(example)

        // 确保组件已完全挂载
        await nextTick()

        // 立即运行代码
        runCode()
    } catch (error) {
        console.error('Failed to initialize playground:', error)
        router.push('/')
    }
})

// 防抖函数
function debounce(fn, delay) {
    let timer = null
    return function (...args) {
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
            fn.apply(this, args)
        }, delay)
    }
}

const debouncedRunCode = debounce(runCode, 600)

// 监听代码变化
watch([
    () => codeState.html,
    () => codeState.css,
    () => codeState.javascript
], () => {
    if (autoRun.value) {
        debouncedRunCode()
    }
}, { deep: true })
</script>

<style>
.playground {
    height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-primary);
}

.toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
    z-index: 10;
    backdrop-filter: blur(10px);
    background: rgba(var(--bg-secondary-rgb), 0.8);
}

.toolbar-actions {
    display: flex;
    gap: var(--space-2);
    margin-left: auto;
}

.tabs {
    display: flex;
    gap: var(--space-2);
}

.tab {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    position: relative;
    padding: var(--space-2) var(--space-3);
    border: none;
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: var(--text-sm);
    border-radius: var(--radius-sm);
}

.tab.active {
    background: var(--primary-color);
    color: white;
}



.tab-icon {
    width: 16px;
    height: 16px;
    background-size: contain;
}

.main-content {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    padding: var(--space-3);
    min-height: 0;
    overflow: hidden;
    position: relative;
}

.main-content.is-fullscreen {
    grid-template-columns: 1fr;
    padding: 0;
    gap: 0;
}

.editor-container {
    overflow: hidden;
    border-radius: var(--radius-md);
    background: var(--bg-secondary);
    transition: all 0.3s ease;
}

.editor-container.hidden {
    display: none;
}

.editor-wrapper {
    height: 100%;
    transition: opacity 0.3s ease;
}

.editor-wrapper.hidden {
    display: none;
}

.editor-status-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-secondary);
    border-top: 1px solid var(--border-color);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.status-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.preview-container {
    overflow: hidden;
    border-radius: var(--radius-md);
    background: white;
    transition: all 0.3s ease;
}

.preview-container.is-fullscreen {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    z-index: 5;
    border-radius: 0;
}

.preview-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-2) var(--space-3);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
}

.preview-title {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text-secondary);
}

.preview-controls {
    display: flex;
    gap: var(--space-2);
}

.btn-icon-small {
    padding: var(--space-1);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-icon-small:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.preview-frame {
    width: 100%;
    height: 100%;
    border: none;
    background: white;
}

.preview-loading {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    background: rgba(var(--bg-primary-rgb), 0.8);
    backdrop-filter: blur(4px);
    z-index: 1;
}

.editor-loading {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    gap: var(--space-3);
    color: var(--text-secondary);
}

.loading-spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--border-color);
    border-top-color: var(--primary-color);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

.btn {
    padding: var(--space-2) var(--space-3);
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn:hover {
    background: var(--border-color);
}

.btn-icon {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.btn-primary {
    background: var(--primary-color);
    color: white;
    border: none;
}

.btn-primary:hover {
    background: var(--primary-color-dark);
}

.btn-primary.is-loading {
    position: relative;
    pointer-events: none;
    opacity: 0.8;
}

.btn-primary.is-loading::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    border: 2px solid white;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.btn-toggle {
    background: none;
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
    display: flex;
    align-items: center;
    gap: 0.4em;
    cursor: pointer;
    transition: all 0.2s;
}

.btn-toggle.active {
    background: var(--primary-color);
    color: #fff;
    border-color: var(--primary-color);
}

.btn-toggle .on {
    color: #4caf50;
    margin-left: 0.3em;
}

.btn-toggle .off {
    color: #f44336;
    margin-left: 0.3em;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

.slide-fade-enter-active,
.slide-fade-leave-active {
    transition: all 0.3s ease;
}

.slide-fade-enter-from,
.slide-fade-leave-to {
    opacity: 0;
    transform: translateX(-20px);
}

.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}

.icon-back::before {
    content: '←';
}

.icon-run::before {
    content: '▶';
}

.icon-fullscreen::before {
    content: '⤢';
}

.icon-exit-fullscreen::before {
    content: '⤓';
}

.icon-refresh::before {
    content: '↻';
}

.icon-info::before {
    content: 'ℹ';
}

.icon-auto-run::before {
    content: '⏱';
}

.btn-exit-fullscreen {
    background: var(--primary-color);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.3em 1em;
    font-size: 1em;
    display: flex;
    align-items: center;
    gap: 0.4em;
    box-shadow: 0 2px 8px 0 rgba(58, 86, 138, 0.10);
}

.btn-exit-fullscreen:hover {
    background: var(--primary-color-dark);
}

@media (max-width: 768px) {
    .main-content {
        grid-template-columns: 1fr;
    }
}
</style>

<style scoped lang="scss">
.playground-container {
    background: #1e1e1e;
    min-height: 100vh;

    .editor-section {
        opacity: 0;
        transform: translateY(20px);
        animation: slideIn 0.5s ease forwards;
    }

    .toolbar {
        background: rgba(30, 30, 30, 0.95);
        backdrop-filter: blur(10px);
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);

        .tool-button {
            padding: 6px 12px;
            border-radius: 4px;
            background: rgba(255, 255, 255, 0.1);
            color: #fff;
            transition: all 0.2s;

            &:hover {
                background: rgba(255, 255, 255, 0.2);
                transform: translateY(-1px);
            }

            &:active {
                transform: translateY(0);
            }
        }
    }

    .status-indicator {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        margin-right: 8px;

        &.running {
            background: #4CAF50;
            box-shadow: 0 0 8px #4CAF50;
            animation: pulse 1.5s infinite;
        }

        &.stopped {
            background: #f44336;
        }
    }
}

@keyframes slideIn {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes pulse {
    0% {
        transform: scale(1);
        opacity: 1;
    }

    50% {
        transform: scale(1.2);
        opacity: 0.8;
    }

    100% {
        transform: scale(1);
        opacity: 1;
    }
}

.split-view {
    transition: all 0.3s ease;

    &.collapsed {
        flex: 0 1 0%;
    }
}

.resize-handle {
    position: relative;
    width: 4px;
    background: rgba(255, 255, 255, 0.1);
    cursor: col-resize;
    transition: background 0.2s;

    &:hover {
        background: rgba(255, 255, 255, 0.2);
    }

    &::after {
        content: '';
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 2px;
        height: 20px;
        background: rgba(255, 255, 255, 0.3);
        border-radius: 1px;
    }
}

.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}

.slide-enter-active,
.slide-leave-active {
    transition: transform 0.3s ease;
}

.slide-enter-from,
.slide-leave-to {
    transform: translateX(100%);
}

.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.spinner {
    width: 50px;
    height: 50px;
    border: 3px solid #f3f3f3;
    border-top: 3px solid #3498db;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}
</style>